Objetivo: obtener información relacionada con la organización y preprocesamiento de datos espaciales, así como trabajar con datos de series temporales.
La organización de datos es la práctica de clasificar y organizar los datos de manera coherente para su fácil uso y acceso.
Es preferible guardar los archivos (correspondientes a una serie de tiempo) con la fecha (y/o hora del día) en el nombre porque:
La organización alfabética de archivos debe corresponder al orden cronológico de los mismos.
Consistencia en el nombre del archivo (longitud y estilo).
Cada archivo de un cierto conjunto de datos debiera tener el mismo nombre base y luego un identificador numérico (fecha, número de iteración, escenario, etc.)
Para asegurar la misma longitud en los nombres, los meses y días del 1 al 9 deben escribirse como 01–09
Al exportar tablas (csv, txt, zoo, etc.) los mismos datos siempre en la misma ubicación (es decir, en la misma fila o columna)
¡Asegúrate de que los valores sin datos no se registren como ceros!
A veces queremos usar archivos específicos para un cierto análisis. Por lo tanto, es útil aprender cómo extraer archivos específicos de un directorio.
Ya hemos visto que podemos listar todos los archivos dentro de una carpeta:
Para seleccionar un subconjunto de estos archivos, podemos usar la función grep. Esta función busca un patrón predefinido en los archivos y devuelve la posición de cada elemento.
Si el nombre base de los archivos no contiene el patrón buscado, podemos usar toda la ruta de los archivos en combinación con el parámetro value:
grep("2011", ssebop_files, value = TRUE)
## [1] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201101.tif"
## [2] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201102.tif"
## [3] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201103.tif"
## [4] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201104.tif"
## [5] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201105.tif"
## [6] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201106.tif"
## [7] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201107.tif"
## [8] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201108.tif"
## [9] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201109.tif"
## [10] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201110.tif"
## [11] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201111.tif"
## [12] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201112.tif"En el caso de que queramos usar el vector de posiciones, debemos seleccionar el subconjunto de archivos de la siguiente manera:
pos <- grep("2011", basename(ssebop_files))
ssebop_2011 <- ssebop_files[pos]
head(ssebop_2011)
## [1] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201101.tif"
## [2] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201102.tif"
## [3] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201103.tif"
## [4] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201104.tif"
## [5] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201105.tif"
## [6] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201106.tif"Esto se puede hacer en una línea:
¿Qué pasa si solo queremos los archivos de cada marzo?
ssebop_march <- ssebop_files[grep("03.tif", basename(ssebop_files))]
head(ssebop_march)
## [1] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201003.tif"
## [2] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201103.tif"
## [3] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201203.tif"
## [4] "../Data/L4_Data_Processing_Data/SSEBop//SSEBop_201303.tif"¡Esto funciona porque los nombres de archivo son lógicos y consistentes!
Por lo general, necesitamos preprocesar los datos brutos para que puedan ser utilizados de la manera que requerimos.
Para preprocesar datos, necesitamos saber cómo se almacenan los datos brutos
Esto significa que necesitamos averiguar parte o la totalidad de lo siguiente:
Sistema de proyección
En este ejemplo, veremos el producto de precipitación CHIRPSv2
Carga los datos brutos de precipitación mensuales de CHIRPSv2 para enero de 2000.
Ahora podemos importar el ráster utilizando el paquete terra.
CHIRPSv2 solo proporciona precipitación en tierra firme. Los valores NA (es decir, donde no se realiza ninguna estimación) se almacenan originalmente como -9999.
¿Entonces cómo podemos crear un conjunto de datos que luego podamos utilizar en todas partes?
Ahora que los datos han sido pre-procesados, podemos guardarlos como un nuevo ráster.
A veces, tenemos que agregar datos para analizar diferentes escalas temporales. Un producto puede ser obtenido a escala diaria, pero se pueden requerir estimaciones mensuales o anuales. En este ejemplo, queremos derivar un raster de precipitación anual a partir de los rásters mensuales de CHIRPS para los años 2000–2003.
head(chirps_files)
## [1] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-01.tif"
## [2] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-02.tif"
## [3] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-03.tif"
## [4] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-04.tif"
## [5] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-05.tif"
## [6] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-06.tif"
tail(chirps_files)
## [1] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2003-07.tif"
## [2] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2003-08.tif"
## [3] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2003-09.tif"
## [4] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2003-10.tif"
## [5] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2003-11.tif"
## [6] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2003-12.tif"Ahora, queremos generar archivos ráster anuales sumando los 12 archivos mensuales para cada año.
years <- substr(basename(chirps_files), 15, 18)
print(years)
## [1] "2000" "2000" "2000" "2000" "2000" "2000" "2000" "2000" "2000" "2000"
## [11] "2000" "2000" "2001" "2001" "2001" "2001" "2001" "2001" "2001" "2001"
## [21] "2001" "2001" "2001" "2001" "2002" "2002" "2002" "2002" "2002" "2002"
## [31] "2002" "2002" "2002" "2002" "2002" "2002" "2003" "2003" "2003" "2003"
## [41] "2003" "2003" "2003" "2003" "2003" "2003" "2003" "2003"¿Cómo podemos escribir un ciclo for para generar un archivo raster anual a la vez?
output_dir <- "C:/User/CHIRPSv2_annual"
for(i in 1:length(unique_years)){
# Aquí extraemos las rutas del año i
positions <- grep(unique_years[i], basename(chirps_files))
files <- chirps_files[positions]
# Luego apilamos los archivos mensuales del año i
files <- rast(files)
# Ahora tenemos que agregar la precipitación mensual para obtener la precipitación anual.
annual <- sum(files)
# Finalmente, podemos exportar el archivo. Sin embargo, primero tenemos que crear un nombre diferente (e identificable)
# para cada año. Así que incluiremos el año en el nuevo nombre de archivo.
name <- paste0("CHIRPS_annual_", unique_years[i])
names(annual) <- name
name <- paste0(name, ".tif")
writeRaster(annual, file.path(output_dir, name), overwrite = TRUE)
}Si deseas ver cómo funciona este ciclo paso a paso, puedes establecer i = 1 (o cualquier otro número dentro del ciclo), y luego ejecutar cada paso individualmente e imprimir/graficar los resultados después de cada paso.
i <- 1
positions <- grep(unique_years[i], basename(chirps_files))
print(positions)
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
files <- chirps_files[positions]
head(files)
## [1] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-01.tif"
## [2] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-02.tif"
## [3] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-03.tif"
## [4] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-04.tif"
## [5] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-05.tif"
## [6] "../Data/L4_Data_Processing_Data/CHIRPS_monthly/chirps_monthly2000-06.tif"files <- rast(files)
print(files)
## class : SpatRaster
## dimensions : 2000, 7200, 12 (nrow, ncol, nlyr)
## resolution : 0.05, 0.05 (x, y)
## extent : -180, 180, -50, 50 (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326)
## sources : chirps_monthly2000-01.tif
## chirps_monthly2000-02.tif
## chirps_monthly2000-03.tif
## ... and 9 more source(s)
## names : chirp~00-01, chirp~00-02, chirp~00-03, chirp~00-04, chirp~00-05, chirp~00-06, ...
## min values : 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, ...
## max values : 1251.456, 1467.558, 1222.492, 1224.301, 1322.237, 1584.747, ...
annual <- sum(files)
##
|---------|---------|---------|---------|
=========================================
name <- paste0("CHIRPS_annual_", unique_years[i])
names(annual) <- name
name <- paste0(name, ".tif")
print(name)
## [1] "CHIRPS_annual_2000.tif"
writeRaster(annual, file.path(output_dir, name), overwrite = TRUE)Veamos lo que se guarda ahora en la carpeta CHIRPS_anual.
Ahora, en R:
annual_files <- list.files(output_dir, full.names = TRUE)
print(annual_files)
## [1] "../Data/L4_Data_Processing_Data/CHIRPS_annual/CHIRPS_annual_2000.tif"
## [2] "../Data/L4_Data_Processing_Data/CHIRPS_annual/CHIRPSv2_annual_2000.tif"
## [3] "../Data/L4_Data_Processing_Data/CHIRPS_annual/CHIRPSv2_annual_2001.tif"
## [4] "../Data/L4_Data_Processing_Data/CHIRPS_annual/CHIRPSv2_annual_2002.tif"
## [5] "../Data/L4_Data_Processing_Data/CHIRPS_annual/CHIRPSv2_annual_2003.tif"Veamos los rásters anuales.
También podríamos haber utilizado el comando %in% en el ejemplo anterior. Este comando devuelve las posiciones de valores específicos en un vector.
a <- c(10, 10, 20, 20, 30, 30, 40, 40)
a %in% 20
## [1] FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSESi usamos el comando %in% en combinación con el comando which:
for(i in 1:length(unique_years)){
positions <- which(years %in% unique_years[i])
files <- chirps_files[positions]
# Luego apilamos los archivos mensuales del año i
files <- rast(files)
# Ahora tenemos que agregar la precipitación mensual para obtener la precipitación anual
annual <- sum(files)
# Finalmente, exportamos el archivo. Sin embargo, primero tenemos que crear un nombre diferente (e identificable)
# para cada año. Por lo tanto, incluiremos el año en el nuevo nombre del archivo.
name <- paste0("CHIRPS_annual_", unique_years[i])
names(annual) <- name
name <- paste0(name, ".tif")
writeRaster(annual, file.path(output_dir, name), overwrite = TRUE)
}En muchas ocasiones, trabajaremos con series de tiempo largas y querremos extraer datos durante un período particular. Ya hemos visto cómo extraer datos de columnas específicas (ver ejemplo en Módulo 2).
Aquí, veremos cómo seleccionar subconjuntos de datos de acuerdo a un periodo temporal y cómo calcular estadísticas mensuales. Para este propósito, utilizaremos el paquete hydroTSM, que está diseñado para manejar eficientemente las series de tiempo. Aunque hydroTSM fue diseñado para el campo de la hidrología, es un paquete eficiente para manejar series temporales, independientemente del campo científico en el que estemos trabajando.
El paquete zoo es útil cuando tenemos que trabajar con series de tiempo. Mientras que los comandos read.table o read.csv devuelven las fechas en la columna respectiva, el objeto zoo incluye las fechas en el índice del objeto.
Tenga en cuenta que el paquete hydroTSM carga por defecto el paquete zoo.
Primero leeremos el archivo csv:
head(temp_data)
## Date tmax tmin
## 1 1950-01-01 16.87414245 2.267171503
## 2 1950-01-02 14.12995701 7.472945504
## 3 1950-01-03 12.87256241 -0.322433109
## 4 1950-01-04 12.7848237 -3.291659449
## 5 1950-01-05 15.15733243 -3.763536855
## 6 1950-01-06 20.72999248 -5.898691615
dim(temp_data)
## [1] 25567 3
summary(temp_data)
## Date tmax tmin
## Length:25567 Length:25567 Length:25567
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :characterLos valores NA se han guardado como esta cadena de texto en el archivo csv proporcionado (#N/A). Volveremos a leer el archivo csv, especificando el parámetro na.strings para interpretar los NA correctamente.
tail(temp_data)
## Date tmax tmin
## 25562 2019-12-26 14.67704 7.608191
## 25563 2019-12-27 NA NA
## 25564 2019-12-28 NA NA
## 25565 2019-12-29 NA NA
## 25566 2019-12-30 15.46794 7.934365
## 25567 2019-12-31 21.43409 10.980799
summary(temp_data)
## Date tmax tmin
## Length:25567 Min. : 7.407 Min. :-7.701
## Class :character 1st Qu.:21.273 1st Qu.: 7.584
## Mode :character Median :25.868 Median :12.026
## Mean :25.874 Mean :11.614
## 3rd Qu.:30.341 3rd Qu.:15.742
## Max. :45.716 Max. :27.670
## NA's :1881 NA's :1843Utilizaremos la función zoo para convertir el objeto temp.data a un objeto zoo.
Para nuestro ejemplo:
¡Las fechas no corresponden a una columna de datos! Solo hay dos columnas (tmax y tmin).
head(temp_data)
## tmax tmin
## 1950-01-01 16.87414 2.2671715
## 1950-01-02 14.12996 7.4729455
## 1950-01-03 12.87256 -0.3224331
## 1950-01-04 12.78482 -3.2916594
## 1950-01-05 15.15733 -3.7635369
## 1950-01-06 20.72999 -5.8986916
summary(temp_data)
## Index tmax tmin
## Min. :1950-01-01 Min. : 7.407 Min. :-7.701
## 1st Qu.:1967-07-02 1st Qu.:21.273 1st Qu.: 7.584
## Median :1984-12-31 Median :25.868 Median :12.026
## Mean :1984-12-31 Mean :25.874 Mean :11.614
## 3rd Qu.:2002-07-01 3rd Qu.:30.341 3rd Qu.:15.742
## Max. :2019-12-31 Max. :45.716 Max. :27.670
## NA's :1881 NA's :1843
dim(temp_data)
## [1] 25567 2Para acceder a las fechas, usamos la función index.
dates <- index(temp_data)
head(dates)
## [1] "1950-01-01" "1950-01-02" "1950-01-03" "1950-01-04" "1950-01-05"
## [6] "1950-01-06"
tail(dates)
## [1] "2019-12-26" "2019-12-27" "2019-12-28" "2019-12-29" "2019-12-30"
## [6] "2019-12-31"
index(temp_data)[3:5]
## [1] "1950-01-03" "1950-01-04" "1950-01-05"Podemos usar la función window para extraer datos durante un período de tiempo específico.
temp_1990s <- window(temp_data, start = "1990-01-01", end = "1999-12-31")
summary(temp_1990s)
## Index tmax tmin
## Min. :1990-01-01 Min. :10.59 Min. :-1.821
## 1st Qu.:1992-07-01 1st Qu.:21.99 1st Qu.: 9.007
## Median :1994-12-31 Median :26.34 Median :13.071
## Mean :1994-12-31 Mean :26.41 Mean :12.708
## 3rd Qu.:1997-07-01 3rd Qu.:30.62 3rd Qu.:16.543
## Max. :1999-12-31 Max. :44.71 Max. :26.289
## NA's :195 NA's :180Podemos utilizar la función daily2monthly para calcular estadísticas para cada mes.
x: es el objeto zoo. FUN: función a aplicar. na.rm: valor lógico. ¿Deben eliminarse los NAs?
Nota: el paquete hydroTSM incluye conversiones a valores mensuales, estacionales y anuales.
Para nuestro ejemplo, calculemos la temperatura media máxima y mínima para cada mes del año 1990.
monthly_temp1990s <- daily2monthly(temp_1990s, mean, na.rm = TRUE)
head(monthly_temp1990s)
## tmax tmin
## 1990-01-01 22.13839 6.021942
## 1990-02-01 20.89031 6.032163
## 1990-03-01 22.10266 10.087943
## 1990-04-01 23.71689 13.046162
## 1990-05-01 25.62137 13.678022
## 1990-06-01 30.10750 16.801449
summary(monthly_temp1990s)
## Index tmax tmin
## Min. :1990-01-01 Min. :18.73 Min. : 5.058
## 1st Qu.:1992-06-23 1st Qu.:22.24 1st Qu.: 9.054
## Median :1994-12-16 Median :26.21 Median :12.645
## Mean :1994-12-16 Mean :26.35 Mean :12.649
## 3rd Qu.:1997-06-08 3rd Qu.:30.21 3rd Qu.:16.650
## Max. :1999-12-01 Max. :35.33 Max. :20.311
## NA's :1 NA's :1Para visualizar la serie de tiempo almacenada en un objeto zoo como un gráfico:
En su forma más simple, un ráster consiste en una matriz de celdas organizadas en filas y columnas. Para una lista más detallada de los controladores de archivos ráster, haga clic aquí. Algunos de estos controladores de archivos ráster son:
La importación de archivos NetCDF en R es muy sencilla. Utilizaremos la misma función rast de la siguiente manera:
Ahora podemos visualizar el objeto chirps:
Para exportar archivos ráster con formatos diferentes, podemos utilizar la función writeRaster. En caso de que deseemos exportar un archivo NetCDF, podemos utilizar alternativamente la función writeCDF.
Ahora que ya has procesado algunos datos grandes en tu computadora, veamos los archivos temporales.
Ve a la siguiente ruta de archivo en el administrador de archivos: C:\Users\nombre-de-usuario\AppData\Local\Temp
Si estás analizando grandes cantidades de datos, los archivos temporales comenzarán a ocupar mucho espacio. Hay algunas opciones:
Elimina periódicamente los archivos temporales (estos archivos se eliminan al reiniciar la computadora).
Indícale a R que escriba los archivos temporales ráster en otra ubicación (por ejemplo, una unidad externa). Aún se deberán eliminar los archivos más tarde. Ten en cuenta que esto es solo para los archivos ráster.
En Windows, puedes acceder a los archivos temporales del sistema escribiendo %temp% en el cuadro de búsqueda.
Para cambiar el directorio donde se almacenan los archivos temporales, se puede usar la función rasterOptions.
Además, puedes agregar código para eliminar archivos temporales. Esto se puede hacer con la función file.remove.
Cada núcleo de una CPU puede realizar operaciones por separado de los demás. Si no se dan instrucciones especiales, R solo utilizará un núcleo de la computadora. Si se necesita procesar cantidades muy grandes de datos, consulta los siguientes enlaces: